import "./cdpLoading.css";
import Vue from 'vue';
import Loading from './cdpLoading.vue';
import { addClass, removeClass, getStyle } from 'element-ui/src/utils/dom';

const Mask = Vue.extend(Loading);


const toggleLoading = (el, binding) => {
    if (binding.value) {
        Vue.nextTick(() => {
            if (binding.modifiers.fullscreen) {
                el.originalPosition = getStyle(document.body, 'position');
                el.originalOverflow = getStyle(document.body, 'overflow');

                addClass(el.mask, 'is-fullscreen');
                insertDom(document.body, el, binding);
            } else {
                removeClass(el.mask, 'is-fullscreen');

                if (binding.modifiers.body) {
                    el.originalPosition = getStyle(document.body, 'position');

                    ['top', 'left'].forEach(property => {
                        const scroll = property === 'top' ? 'scrollTop' : 'scrollLeft';
                        el.maskStyle[property] = el.getBoundingClientRect()[property] + document.body[scroll] + document.documentElement[scroll] + 'px';
                    });
                    ['height', 'width'].forEach(property => {
                        el.maskStyle[property] = el.getBoundingClientRect()[property] + 'px';
                    });

                    insertDom(document.body, el, binding);
                } else {
                    el.originalPosition = getStyle(el, 'position');
                    insertDom(el, el, binding);
                }
            }
        });
    } else {
        if (el.domVisible) {
            el.instance.$on('after-leave', _ => {
                el.domVisible = false;
                const target = binding.modifiers.fullscreen || binding.modifiers.body ?
                    document.body :
                    el;
                removeClass(target, 'el-loading-parent--relative');
                removeClass(target, 'el-loading-parent--hidden');
            });
            el.instance.visible = false;
        }
    }
};
const insertDom = (parent, el, binding) => {
    if (!el.domVisible && getStyle(el, 'display') !== 'none' && getStyle(el, 'visibility') !== 'hidden') {
        Object.keys(el.maskStyle).forEach(property => {
            el.mask.style[property] = el.maskStyle[property];
        });

        if (el.originalPosition !== 'absolute' && el.originalPosition !== 'fixed') {
            addClass(parent, 'el-loading-parent--relative');
        }
        if (binding.modifiers.fullscreen && binding.modifiers.lock) {
            addClass(parent, 'el-loading-parent--hidden');
        }
        el.domVisible = true;

        parent.appendChild(el.mask);
        Vue.nextTick(() => {
            el.instance.visible = true;
        });
        el.domInserted = true;
    }
};
const close = (el, binding) => {
    el.instance.setText(el.getAttribute('element-loading-text'));
    if (binding.oldValue !== binding.value) {
        toggleLoading(el, binding);
    }
};
export default {
    bind: function(el, binding, vnode) {
        const textExr = el.getAttribute('element-loading-text');
        const spinnerExr = el.getAttribute('element-loading-spinner');
        const backgroundExr = el.getAttribute('element-loading-background');
        const vm = vnode.context;
        const mask = new Mask({
            el: document.createElement('div'),
            data: {
                text: vm && vm[textExr] || textExr,
                spinner: vm && vm[spinnerExr] || spinnerExr,
                background: vm && vm[backgroundExr] || backgroundExr,
                fullscreen: !!binding.modifiers.fullscreen
            }
        });
        el.instance = mask;
        el.mask = mask.$el;
        el.maskStyle = {};
        toggleLoading(el, binding);
    },
    update: function(el, binding) {
        el.instance.setNum(0)
        el.instance.getNum()
        close(el, binding)
    },
    unbind: function(el, binding) {
        //console.log(el.instance.num)
        if (el.domInserted) {
            el.mask &&
                el.mask.parentNode &&
                el.mask.parentNode.removeChild(el.mask);
        }
    }
};